package com.witfortos.common.http.interceptor

import com.witfortos.common.utils.SPUtils
import okhttp3.*
import okhttp3.internal.platform.Platform
import okhttp3.internal.platform.Platform.INFO
import org.json.JSONArray
import org.json.JSONException
import org.json.JSONObject
import java.io.IOException
import java.util.concurrent.TimeUnit

/**
 * 借鉴其他Demo里的日志打印
 * #当日志比较多时，有时候会出现输出不全的情况
 */
class LoggingInterceptor : Interceptor {

    private var tag: String = "HttpLogging"
    var isDebug: Boolean = false
    var type = INFO
    var requestTag: String = tag
    var responseTag: String = tag
    var level = Level.BASIC
    private val headers = Headers.Builder()
    var logger: Logger? = null


    interface Logger {
        fun log(level: Int, tag: String, msg: String)

        companion object {
            val DEFAULT: Logger = object : Logger {
                override fun log(level: Int, tag: String, msg: String) {
                    Platform.get().log(level, msg, null)
                }
            }
        }
    }

    @Throws(IOException::class)
    override fun intercept(chain: Interceptor.Chain): Response {


        val request = chain.request()
                .newBuilder()
                .addHeader("Content-Type", "application/json;charset=UTF-8")
                .addHeader("Accept", "application/json")
                .header("Accept-Encoding", "")
                .addHeader("Cookie", "seezoon=" + SPUtils.getInstance().getCookies())
                .build()


        val response = chain.proceed(request)


        if (!isDebug || level == Level.NONE) {
            return chain.proceed(request)
        }
        val requestBody = request.body()

        var rContentType: MediaType? = null
        if (requestBody != null) {
            rContentType = request.body()!!.contentType()
        }

        var rSubtype: String? = null
        if (rContentType != null) {
            rSubtype = rContentType.subtype()
        }

        if (rSubtype != null && (rSubtype.contains("json")
                        || rSubtype.contains("xml")
                        || rSubtype.contains("plain")
                        || rSubtype.contains("html"))
        ) {
            Printer.printJsonRequest(this, request)
        } else {
            Printer.printFileRequest(this, request)
        }

        val st = System.nanoTime()

        val segmentList = request.url().encodedPathSegments()
        val chainMs = TimeUnit.NANOSECONDS.toMillis(System.nanoTime() - st)
        val header = response.headers().toString()
        val code = response.code()
        val isSuccessful = response.isSuccessful
        val responseBody = response.body()
        val contentType = responseBody!!.contentType()

        var subtype: String? = null
        val body: ResponseBody

        if (contentType != null) {
            subtype = contentType.subtype()
        }

        if (subtype != null && (subtype.contains("json")
                        || subtype.contains("xml")
                        || subtype.contains("plain")
                        || subtype.contains("html"))
        ) {
            val bodyString = responseBody.string()
            Printer.printJsonResponse(
                    this,
                    chainMs,
                    isSuccessful,
                    code,
                    header,
                    bodyString,
                    segmentList
            )
            body = ResponseBody.create(contentType, bodyString)
        } else {
            Printer.printFileResponse(this, chainMs, isSuccessful, code, header, segmentList)
            return response
        }

        return response.newBuilder().body(body).build()
    }

    private fun getHeaders(): Headers = headers.build()

    private val JSON_INDENT = 3

    fun getJsonString(msg: String): String? {
        val message: String
        message = try {
            if (msg.startsWith("{")) {
                val jsonObject = JSONObject(msg)
                jsonObject.toString(JSON_INDENT)
            } else if (msg.startsWith("[")) {
                val jsonArray = JSONArray(msg)
                jsonArray.toString(JSON_INDENT)
            } else {
                msg
            }
        } catch (e: JSONException) {
            msg
        }
        return message
    }
}
